package org.dromara.app.cssUtils;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.batch.MybatisBatch;
import com.tencentcloudapi.common.AbstractModel;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.iai.v20180301.IaiClient;
import com.tencentcloudapi.iai.v20180301.models.CompareFaceRequest;
import com.tencentcloudapi.iai.v20180301.models.CompareFaceResponse;
import jakarta.servlet.http.HttpServletRequest;
import org.dromara.app.appParams.AppLianXiLogin;
import org.dromara.app.appReturn.AppTalentHeatReturn;
import org.dromara.app.domain.SkAppUser;
import org.dromara.common.core.constant.CacheNames;
import org.dromara.common.core.domain.R;
import org.dromara.common.redis.config.RedisConfig;
import org.dromara.common.redis.utils.RedisUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;

@Service
public class CssUtils {

    private static final AtomicLong ORDER_NUMBER = new AtomicLong(0);

    //经验参数信息
    private static Map<String, Object> jingyanMap = new HashMap<>();


    static {
        jingyanMap.put("自己发布组局", "get_jingyan_wode");
        jingyanMap.put("我的直推在达人模块下单", "get_jingyan_wodezhituidaren");
        jingyanMap.put("自己连续登录4天", "get_jingyan_zijilianxidenglu");
        jingyanMap.put("自己充值会员", "get_jingyan_zijichongzhihuiyuan");
        jingyanMap.put("我的直推发布组局", "get_jingyan_wodezhitui");
        jingyanMap.put("自己在达人模块下单", "get_jingyan_wodedaren");
        jingyanMap.put("自己参与组局", "get_jingyan_wodeyueju");
        jingyanMap.put("我的直推参与组局", "get_jingyan_wodezhituiyueju");
        jingyanMap.put("我的直推连续登录4天", "get_jingyan_zhituilianxidenglu");
        jingyanMap.put("我的直推充值会员", "get_jingyan_zhituichongzhihuiyuan");
    }

    //分销参数信息
    private static Map<String, Object> fenxiaoMap = new HashMap<>();

    static {
        fenxiaoMap.put("达人开会员佣金", "get_fenxiao_drkhy_yj");
        fenxiaoMap.put("推广达人开会员佣金", "get_fenxiao_tgdrkhy_yj");
        fenxiaoMap.put("合伙人开会员佣金", "get_fenxiao_hhrkhy_yj");
        fenxiaoMap.put("城市代理开会员佣金", "get_fenxiao_citydlkhy_yj");

        fenxiaoMap.put("达人订单佣金", "get_fenxiao_drorder_yj");
        fenxiaoMap.put("推广达人订单佣金", "get_fenxiao_tgdrorder_yj");
        fenxiaoMap.put("合伙人订单佣金", "get_fenxiao_hhrorder_yj");
        fenxiaoMap.put("城市代理订单佣金", "get_fenxiao_citydlorder_yj");
        fenxiaoMap.put("普通用户成为推广达人邀请人数", "get_fenxiao_citydlorder_yaoqing");
    }

    //会员参数信息
    private static Map<String, Object> huiyuanMap = new HashMap<>();

    static {
        huiyuanMap.put("白银会员每周可查看达人微信号次数", "get_huiyuan_week_number_baiyin");
        huiyuanMap.put("黄金会员每周可查看达人微信号次数", "get_huiyuan_week_number_huangjin");
        huiyuanMap.put("钻石会员每周可查看达人微信号次数", "get_huiyuan_week_number_zuanshi");
        huiyuanMap.put("黄金下单享受折扣优惠", "get_huiyuan_zhekou_huangjin");
        huiyuanMap.put("钻石下单享受折扣优惠", "get_huiyuan_zhekou_zuanshi");
        huiyuanMap.put("白银下单享受折扣优惠", "get_huiyuan_zhekou_baiyin");
        huiyuanMap.put("白银每天可以私聊达人的数量", "get_huiyuan_day_siliao_baiyin");
        huiyuanMap.put("黄金每天可以私聊达人的数量", "get_huiyuan_day_siliao_huangjin");
        huiyuanMap.put("钻石每天可以私聊达人的数量", "get_huiyuan_day_siliao_zuanshi");
    }

    /**
     * 获取经验参数
     */
    public static Object getJingYanConfig(String key) {
        if (jingyanMap.get(key) == null) {
            CssExceptionDescription.errorMsg(10010);
        }
        return jingyanMap.get(key);
    }

    /**
     * 获取会员参数
     */
    public static Object getHuiYuanConfig(String key) {
        if (huiyuanMap.get(key) == null) {
            CssExceptionDescription.errorMsg(10010);
        }
        return huiyuanMap.get(key);
    }

    /**
     * 获取分销参数
     */
    public static Object getFenXiaoConfig(String key) {
        if (fenxiaoMap.get(key) == null) {
            CssExceptionDescription.errorMsg(10010);
        }
        return fenxiaoMap.get(key);
    }


    /**
     * 获取用户ID
     * auto 蔡帅帅
     *
     * @param req
     * @return
     */
    public static Long getUserId(HttpServletRequest req) {
        Long userId = null;
        //是否是需要拦截的
        String token = req.getHeader("appToken");
        if (token == null || token.isEmpty()) {        // token 是否为空
            //APP未登录
            CssExceptionDescription.errorMsg(40001);
        } else {
            if (RedisUtils.getCacheObject(RedisServiceUtils.loginToken(token)) == null) {
                CssExceptionDescription.errorMsg(40001);
            }
            userId = Long.parseLong(RedisUtils.getCacheObject(RedisServiceUtils.loginToken(token)).toString());
            //判断token是否在redis存在
            if (userId == null || String.valueOf(userId).isEmpty()) {
                CssExceptionDescription.errorMsg(40001);
            } else {
                Duration duration = Duration.of(3, ChronoUnit.DAYS);
                RedisUtils.expire(token, duration);
                //更新在线用户
                Duration zaixian = Duration.of(2, ChronoUnit.HOURS);
                RedisUtils.setCacheObject(RedisServiceUtils.getOnlineUsersTime()+":"+userId, userId, zaixian);
            }
        }

        return userId;
    }

    /**
     * 随机数
     *
     * @return
     */

    public static int getRandom() {
        Random random = new Random();
        int minValue = 1000;
        int maxValue = 9999;
        int randomInt = random.nextInt(maxValue - minValue + 1) + minValue;
        return randomInt;
    }


    /**
     * 生成订单
     */
    public static String generateOrderNumber() {
        // 生成格式: YYYYMMDDXXXX, 其中XXXX是自增长的AtomicLong值
        return DateUtil.format(new Date(), DatePattern.PURE_DATETIME_MS_FORMAT) + "-" + ORDER_NUMBER.incrementAndGet() + "-" + RandomUtil.randomNumbers(4);
    }


    //两个时间间隔分钟
    public static int jianGeDay(String startTime, String endTime) {
        LocalDateTime start = LocalDateTime.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime end = LocalDateTime.parse(endTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Duration duration = Duration.between(start, end);
        return Integer.valueOf(duration.toMinutes() + "");
    }



    public static void saveOnlionUser(SkAppUser user) {
        /**
         * 更新用户信息到redis
         */
        AppTalentHeatReturn app = BeanUtil.copyProperties(user, AppTalentHeatReturn.class);
        RedisUtils.setCacheMapValue(RedisServiceUtils.getOnlineUsers(), user.getId().toString(), app);

    }

    public static String getOpenId(String appId, String appSecret, String code) {
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret=" + appSecret + "&code=" + code + "&grant_type=authorization_code";
        String result = HttpUtil.get(url);
        JSONObject rtnJson = new JSONObject();
        String openid = "";
        if (StringUtils.isNotBlank(result)) {
            JSONObject jsonObject = JSON.parseObject(result);
            if (jsonObject.containsKey("openid")) {
                openid = jsonObject.getString("openid");
                rtnJson.put("openid", openid);
            }
        }
        return openid;
    }

    /**
     * 更新连续登录
     *
     * @param user
     */
    public static AppLianXiLogin updateLianXiLogin(SkAppUser user) {
        AppLianXiLogin appLianXiLogin = RedisUtils.getCacheMapValue(RedisServiceUtils.getLianXiLogin(), user.getId() + "");
        if (appLianXiLogin != null) {
            //不是 今天的数据
            if (!DateUtil.format(appLianXiLogin.getTime(),DatePattern.NORM_DATE_PATTERN).equals(DateUtil.format(new Date(),DatePattern.NORM_DATE_PATTERN))){
                //判断是否是昨天的数据
                Date time = DateUtil.offset(new Date(), DateField.DAY_OF_MONTH,-1);
                if(!DateUtil.format(appLianXiLogin.getTime(),DatePattern.NORM_DATE_PATTERN).equals(DateUtil.format(time,DatePattern.NORM_DATE_PATTERN))){
                    //不是昨天  重新初始化
                    appLianXiLogin = new AppLianXiLogin();
                    appLianXiLogin.setTime(new Date());
                    appLianXiLogin.setNum(1);
                    chushihuaupdateLianXiLogin(user.getId(),appLianXiLogin);
                }else{
                    //是昨天更新数据
                    appLianXiLogin.setNum(appLianXiLogin.getNum()+1);
                    appLianXiLogin.setTime(new Date());
                    chushihuaupdateLianXiLogin(user.getId(),appLianXiLogin);
                }

            }
        }else{
            appLianXiLogin = new AppLianXiLogin();
            appLianXiLogin.setTime(new Date());
            appLianXiLogin.setNum(1);
            chushihuaupdateLianXiLogin(user.getId(),appLianXiLogin);
        }
        return appLianXiLogin;
    }

    public static void chushihuaupdateLianXiLogin(Long userId,AppLianXiLogin appLianXiLogin) {
        RedisUtils.setCacheMapValue(RedisServiceUtils.getLianXiLogin(), userId + "",appLianXiLogin);
    }

    public static boolean isValidYearMonth(String text) {
        // 定义年月的正则表达式
        String regex = "^\\d{4}-\\d{2}$";
        // 检查文本是否匹配正则表达式
        if (text.matches(regex)) {
            try {
                // 使用DateTimeFormatter解析字符串
                SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM");
                formatter.parse(text);
                // 如果没有异常抛出，说明是有效的年月格式
                return true;
            } catch (Exception e) {
                // 字符串不是有效的日期
                return false;
            }
        }else{
            return false;
        }
    }

    /**
     * 发送验证码
     * @param phone
     */
    public static void send(String phone,String content) {

        String url = "action=send&userid=1544&account=shangke&password=shangke183&mobile="+phone+"&content="+content+"&sendTime=&extno=&rt=json";
        HttpRequest httpPost =  HttpUtil.createPost("http://www.106dxcx.com/sms.aspx?"+url);
        httpPost.header("Content-Type","application/x-www-form-urlencoded");
        HttpResponse response = httpPost.execute();
        String result = response.body();
        System.out.println(result);
    }
    /**
     * 经纬度距离计算
     */
    public static double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
        double phi1 = Math.toRadians(lat1);
        double phi2 = Math.toRadians(lat2);
        double deltaPhi = Math.toRadians(lat2 - lat1);
        double deltaLambda = Math.toRadians(lon2 - lon1);

        double a = Math.sin(deltaPhi / 2) * Math.sin(deltaPhi / 2) +
            Math.cos(phi1) * Math.cos(phi2) *
                Math.sin(deltaLambda / 2) * Math.sin(deltaLambda / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

        return 6371 * c;
    }

    public static int faaceDuiBi(String host,String SecretId,String SecretKey,String imageUrl1,String imageUrl2) throws TencentCloudSDKException {
        Credential cred = new Credential(SecretId, SecretKey);
        // 实例化一个http选项，可选的，没有特殊需求可以跳过
        HttpProfile httpProfile = new HttpProfile();
        httpProfile.setEndpoint(host);
        // 实例化一个client选项，可选的，没有特殊需求可以跳过
        ClientProfile clientProfile = new ClientProfile();
        clientProfile.setHttpProfile(httpProfile);
        // 实例化要请求产品的client对象,clientProfile是可选的
        IaiClient client = new IaiClient(cred, "", clientProfile);
        // 实例化一个请求对象,每个接口都会对应一个request对象
        CompareFaceRequest req = new CompareFaceRequest();
        req.setUrlA(imageUrl1);
        req.setUrlB(imageUrl2);
        // 返回的resp是一个CompareFaceResponse的实例，与请求对象对应
        CompareFaceResponse resp = client.CompareFace(req);
        int result = Float.compare(resp.getScore(),60f);
//        if (result < 0) {
//            throw new RuntimeException("人脸图对比不通过");
//        }
        // 输出json格式的字符串回包
        System.out.println(AbstractModel.toJsonString(resp));
        return result;
    }

    public static void main(String[] args) {

    }
}
